/*
 * @Author: 李金深 2896583081@qq.com
 * @Date: 2023-06-08 15:14:13
 * @LastEditors: 李金深 2896583081@qq.com
 * @LastEditTime: 2023-09-05 13:53:18
 * @FilePath: /com.huizhouyiren.web.d0101/src/stores/user.js
 * @Description: 用户信息相关
 */

import { defineStore } from 'pinia'
import mitt from '@/mitt/index.js'
import { throttle, debounce } from '@/utils/tools' // parseDate
import { useUser } from './user'
import { useEmail } from './email'
import { useSystem } from './system'
import {
  getLatelyListRequest,
  getEmoticonRequest,
  getChatHistoryRequest,
  getFriendListRequest,
  getCustomerRequest
} from '@/api/chat'
import gifEmoteMap from '@/utils/gifEmoteMap.js'
import emote from '@/utils/emote.js'

export const useChat = defineStore('chat', {
  state: () => {
    return {
      socket: null,
      messageQueue: [],
      setIntervalWesocketPush: null,
      emoteList: [], //表情包
      customEmote: [], //自定义表情贴图
      emoteObject: {}, // 存储所有表情，本地表情和自定义表情图, 用于解析表情信息
      lately: {
        // 最近联系人
        page: 1,
        pagesize: 500,
        list: [],
        showEmpty: false
      },
      latelyList: [], // 最近联系人原始数据
      friend: {
        list: [],
        page: 1,
        pagesize: 500,
        showEmpty: false
      },
      originFiendList: [],
      chatFlag: false, // 区分有其它页面点击聊天（需要处理该用户是否在聊天列表里的情况）和在聊天列表点击聊天的标识
      chatUserInfo: {}, // 当前聊天用户的信息
      chatRecord: {
        // 聊天记录
        list: [],
        page: 1,
        pagesize: 25,
        maxPage: 1,
        loadingStatus: 'loading'
      },
      list: [], // 聊天记录原始数据
      isCompleted: false, // 聊天记录是否加载完
      isLoading: false, // 消息加载状态
      showEmpty: false, // 是否显示消息空省状态
      loadingMore: false, // 消息加载更多状态
      unread: 0,
      isForward: false, // 转发消息的标识
      customer: {} // 客服
    }
  },
  actions: {
    /**
     * @description: 获取客服
     * @return {*}
     */
    getCustomer(callback = () => {}) {
      getCustomerRequest().then((res) => {
        if (res.code == 200) {
          let data = {
            ...res.data,
            member_id: res.data.id,
            to_mid: res.data.id
          }
          this.customer = data
          callback()
        } else {
          mitt.emit('messageTip', {
            type: 'error',
            msg: res.msg
          })
        }
      })
    },
    /**
     * @description: 修改转发消息的标识
     * @return {*}
     */
    updateForwardFlag() {
      this.isForward = !this.isForward
      if (!this.isForward) {
        this.latelyList.forEach((item) => {
          item.isSelect = false
        })
        this.removeFriendSelect()
      }
    },
    // 消息提示处理
    dealChatTip() {
      this.unread = 0
      for (let i = 0; i < 50; i++) {
        if (this.latelyList[i]) {
          this.unread = this.unread + this.latelyList[i].count
        } else {
          mitt.emit('updateCount', {
            type: 'chat',
            count: this.unread
          })
          return
        }
      }
    },
    /**
     * @description: 搜索
     * @param {*} type
     * @param {*} list
     * @return {*}
     */
    searchFunc({ type, list }) {
      this.lately.list = []
      if (type == 'reset') {
        this.lately.list.push(...this.latelyList)
      } else {
        this.lately.list.push(...list)
      }
      this.lately.list.length == 0
        ? (this.lately.showEmpty = true)
        : (this.lately.showEmpty = false)
    },
    /**
     * @description: 好友搜索
     * @param {*} type
     * @param {*} list
     * @return {*}
     */
    friendSearchFunc({ type, list }) {
      this.friend.list = []
      if (type == 'reset') {
        this.friend.list.push(...this.originFiendList)
      } else {
        this.friend.list.push(...list)
      }
      this.friend.list.length == 0
        ? (this.friend.showEmpty = true)
        : (this.friend.showEmpty = false)
    },
    /**
     * @description: 更新聊天记录
     * @param {*} page
     * @param {*} payload
     * @param {*} type
     * @return {*}
     */
    updateChatRecord({ page, payload }) {
      if (page == 1) {
        this.list = []
      }
      let { data, last_page } = payload
      data.forEach((message) => {
        message.isSelect = false
      })
      this.list.push(...data)
      let list = [...this.list]
      list.reverse()
      this.chatRecord.list = []
      this.chatRecord.list.push(...list)
      this.chatRecord.maxPage = last_page
      this.chatRecord.page = page
      this.chatRecord.list.length == 0 ? (this.showEmpty = true) : (this.showEmpty = false)
      if (last_page == page) {
        this.isCompleted = true
      } else {
        this.isCompleted = false
      }
      setTimeout(() => {
        mitt.emit('messageScrollToBottom')
      }, 10)
      // if (type == 'init') {
      //   setTimeout(() => {
      //     uni.$emit('scroll')
      //   }, 80)
      // } else {
      //   uni.$emit('loadmore')
      // }
    },
    /**
     * @description: 移除聊天记录
     * @return {*}
     */
    removeChatRecord() {
      this.chatUserInfo = {}
      localStorage.removeItem('chatUserInfo')
      this.chatRecord.list = []
      this.chatRecord.page = 1
    },
    /**
     * @description: 新消息上墙
     * @param {*} message
     * @param {*} source 来源  local 本地   push 推送
     * @return {*}
     */
    addChateRecord(message, source = 'local') {
      let id = source == 'local' ? message.to_mid : message.fromid
      if (id == this.chatUserInfo.to_mid) {
        message.isSelect = false
        this.chatRecord.list.push(message)
        this.showEmpty = false
        mitt.emit('messageScrollToBottom', source == 'local' ? false : true)
      }
      source == 'local' ? this.updateLatestNews(id, message) : ''
      this.dealChatTip()
    },
    /**
     * @description: 处理当前用户的未读信息标识
     * @return {*}
     */
    dealChatUserUnread() {
      // this.dealUpdateLatestNews(this.chatUserInfo.to_mid, {}, this.lately.list, true)
      this.dealUpdateLatestNews(this.chatUserInfo.to_mid, {}, this.latelyList, true)
    },
    /**
     * @description: 更新聊天列表最近消息的展示
     * @param {*} id 匹配的id
     * @param {*} message 消息
     * @return {*}
     */
    updateLatestNews(id, message) {
      // this.dealUpdateLatestNews(id, message, this.lately.list)
      this.dealUpdateLatestNews(id, message, this.latelyList)
    },
    /**
     * @description: 更新聊天列表最近消息的处理代码
     * @param {*} id 匹配的id
     * @param {*} message 消息
     * @param {*} list 要处理的数组
     * @param {*} onlyDealUnread 是否只处理未读
     * @return {*}
     */
    dealUpdateLatestNews(id, message, list, onlyDealUnread = false) {
      let index = list.findIndex((item) => {
        return item.to_mid == id
      })
      if (index > -1) {
        onlyDealUnread ? '' : (list[index].textMsg = message.content)
        onlyDealUnread ? '' : (list[index].content_type = message.content_type)
        onlyDealUnread ? '' : (list[index].time = new Date(message.create_time).getTime() / 1000)
        list[index].count = 0
        debounce(
          () => {
            this.dealChatTip()
          },
          1000,
          true
        )
      }
    },
    /**
     * @description: 获取聊天记录
     * @param {*} type
     * @return {*}
     */
    getChatHistory(type = 'init') {
      this.isLoading = false
      this.loadingMore = false
      let page = 1
      if (type == 'loadmore') {
        if (this.chatRecord.maxPage == this.chatRecord.page) {
          return
        }
        page = this.chatRecord.page + 1
      } else {
        // 清理跟上一个用户的聊天记录
        this.updateChatRecord({
          page,
          payload: {
            data: [],
            last_page: 2
          },
          type
        })
      }
      let chatUserInfo = localStorage.getItem('chatUserInfo')
      if (chatUserInfo) {
        chatUserInfo = JSON.parse(chatUserInfo)
      } else {
        return
      }
      page == 1 ? (this.isLoading = true) : (this.loadingMore = true)

      this.showEmpty = false
      getChatHistoryRequest({
        to_mid: chatUserInfo.to_mid,
        page,
        pagesize: this.chatRecord.pagesize
      })
        .then((res) => {
          if (res.code == 200) {
            this.updateChatRecord({
              page,
              payload: res.data,
              type
            })
          } else {
            mitt.emit('messageTip', {
              type: 'error',
              msg: res.msg
            })
          }
        })
        .finally(() => {
          this.loadingMore = false
          this.isLoading = false
        })
    },
    /**
     * @description: 更新当前聊天的用户信息
     * @param {*} payload 用户信息对象
     * @return {*}
     */
    updateChatUserInfo(payload) {
      if (this.chatUserInfo.id == payload.id) {
        return
      }
      this.chatUserInfo = payload
      localStorage.setItem('chatUserInfo', JSON.stringify(this.chatUserInfo))
      this.getChatHistory()
    },
    /**
     * @description: 获取好友列表
     * @param {*} page 页码
     * @return {*}
     */
    getFriendList(page = 1) {
      this.friend.page = page
      if (this.friend.page == 1) {
        this.friend.list = []
        this.originFiendList = []
      }
      getFriendListRequest({
        page: this.friend.page,
        pagesize: this.friend.pagesize
      }).then((res) => {
        if (res.code == 200) {
          let { data, last_page } = res.data
          this.originFiendList.push(...data)
          this.friend.list.push(...data)
          this.friend.page < last_page ? this.getFriendList(this.friend.page + 1) : ''
          this.friend.list.length == 0
            ? (this.friend.showEmpty = true)
            : (this.friend.showEmpty = false)
        } else {
          mitt.emit('messageTip', {
            type: 'error',
            msg: res.msg
          })
        }
      })
    },
    /**
     * @description: 重置好友的选择状态
     * @return {*}
     */
    removeFriendSelect() {
      this.originFiendList.forEach((item) => {
        item.isSelect = false
      })
    },
    updateChatFlag(flag) {
      this.chatFlag = flag
    },
    /**
     * @description: 获取聊天列表
     * @param {*} isInit 是否自动更新当前聊天的用户（聊天列表的第一个用户）
     * @param {*} page 页码
     * @return {*}
     */
    getLatelyList(isInit, page = 1) {
      this.lately.page = page
      if (this.lately.page == 1) {
        this.lately.list = []
        this.latelyList = []
      }
      getLatelyListRequest({ page: this.lately.page, pagesize: this.lately.pagesize }).then(
        (res) => {
          if (res.code == 200) {
            let { data = [], last_page } = res.data
            this.latelyList.push(...data)
            this.lately.list.push(...data)

            if (this.lately.page == 1 && this.lately.list.length > 0 && isInit && !this.chatFlag) {
              this.updateChatUserInfo(this.lately.list[0])
            }

            if (this.lately.page < last_page) {
              this.getLatelyList(false, this.lately.page + 1)
            }
            if ((this.lately.page == last_page || last_page == 0) && this.chatFlag) {
              this.updateLatestList('addChat', this.chatUserInfo, 'latelyList')
              this.updateLatestList('addChat', this.chatUserInfo, 'lately.list')
            }
            this.lately.list.length == 0
              ? (this.lately.showEmpty = true)
              : (this.lately.showEmpty = false)
            this.dealChatTip()
          } else {
            mitt.emit('messageTip', {
              type: 'error',
              msg: res.msg
            })
          }
        }
      )
    },
    /**
     * @description: 关于处理聊天列表的本地更新（删除|置顶|添加新聊天）
     * @param {*} type
     * @param {*} user
     * @param {*} listType
     * @return {*}
     */
    updateLatestList(type, user, listType) {
      let target = listType == 'latelyList' ? this.latelyList : this.lately.list
      let index = target.findIndex((item) => {
        return item.member_id == user.member_id
      })
      let normalIndex = -1
      switch (type) {
        case 'addChat': // 创建新对话
          if (index > -1) {
            user = target[index]
          }
          if (!user.tid) {
            index > -1 ? target.splice(index, 1) : ''
            normalIndex = target.findIndex((item) => {
              return !item.tid
            })
            if (normalIndex == 0) {
              target.unshift(user)
            } else {
              target.splice(normalIndex, 0, user)
            }
          }
          this.lately.showEmpty = false
          this.updateChatFlag(false)
          break
        case 'pinned': // 置顶
          index > -1 ? target.splice(index, 1) : ''
          normalIndex = target.findIndex((item) => {
            return !item.tid
          })
          if (normalIndex == 0) {
            target.unshift(user)
          } else {
            target.splice(normalIndex, 0, user)
          }
          break
        case 'delete': //删除
          index > -1 ? target.splice(index, 1) : ''
          break
      }
    },
    /**
     * @description: 接收信息
     * @param {*} res
     * @return {*}
     */
    receiveMessage(res) {
      const userStore = useUser()
      const result = JSON.parse(res.data)
      if (result.type == 'ping') {
        this.sendSocketMessage({
          type: 'pong'
        })
        return
      }
      // console.log(result)
      if (result.msg_type == 'chatMessage' && result.data.fromid != userStore.userInfo.id) {
        throttle(function () {
          mitt.emit('audioTip')
        }, 1000)
      }
      switch (result.msg_type) {
        case 'chatMessage':
          // 聊天信息
          result.data.id = result.data.cid
          this.addChateRecord(result.data, 'push')
          break
        case 'chatList':
          // 聊天列表
          debounce(
            () => {
              let chatList = result.data.data
              this.dealUpdateChatList(chatList, 'latelyList')
              this.dealUpdateChatList(chatList, 'lately')
              this.dealChatTip()
            },
            1000,
            true
          )
          mitt.emit('messageNotify')
          break
        case 'mailCount':
          // 邮件
          // eslint-disable-next-line no-case-declarations
          const emailStore = useEmail()
          emailStore.updateUnreadEmailCount(result.data)
          mitt.emit('emailNotify')
          break
        case 'system':
          // 系统通知
          // eslint-disable-next-line no-case-declarations
          const systemStore = useSystem()
          systemStore.updateNotifyCount(result?.data?.total)
      }
    },
    /**
     * @description: 处理聊天列表数据的更新
     * @param {*} chatList
     * @param {*} type
     * @return {*}
     */
    dealUpdateChatList(chatList, type) {
      let list = type == 'lately' ? [...this.lately.list] : [...this.latelyList]
      let targetList = type == 'lately' ? this.lately.list : this.latelyList
      chatList.forEach((item) => {
        let index = targetList.findIndex((chat) => {
          return item.member_id == chat.member_id
        })
        if (index > -1) {
          list.splice(index, 1)
        }
      })
      list.unshift(...chatList)
      type == 'lately' ? (this.lately.list = list) : (this.latelyList = list)
    },
    /**
     * @description: 查看支付消息的处理
     * @param {*} message
     * @return {*}
     */
    payforViewMessageDeal(message) {
      if (message.member_id == this.chatUserInfo.member_id) {
        let index = this.chatRecord.list.findIndex((item) => {
          return item.id == message.id
        })
        if (index > -1) {
          this.chatRecord.list[index].content = message.content
        }
      }
    },
    /**
     * @description: 更新表情解析对象
     * @param {*} emoteObject
     * @return {*}
     */
    updateEmoticon({ emoteListObject }) {
      // let emoticonOject = {}
      // customEmote.value.forEach((item) => {
      //   emoticonOject[item.title] = {
      //     src: item.image,
      //     from: 'sys'
      //   }
      // })
      let contractObject = {
        ...emoteListObject
        // ...emoticonOject,
      }
      this.emoteObject = contractObject
    },
    // 初始化表情
    initFaceList() {
      let emoteObject = {}
      gifEmoteMap.map((item, index) => {
        emoteObject[item] = {
          src: emote[`gif${index}`],
          alt: item
          // from: "local",
        }
      })
      let list = []
      let keyList = Object.keys(emoteObject)
      keyList.forEach((key) => {
        list.push(emoteObject[key])
      })
      this.emoteList = list
      this.updateEmoticon({ emoteListObject: emoteObject })
    },
    /**
     * @description: 获取自定义表情
     * @return {*}
     */
    getEmoticon() {
      getEmoticonRequest({}).then((res) => {
        if (res.code == 200) {
          this.customEmote = res.data
        } else {
          mitt.emit('messageTip', {
            type: 'error',
            msg: res.msg
          })
        }
      })
    },
    /**
     * @description: 创建socket连接
     * @return {*}
     */
    createSocket() {
      if (typeof WebSocket != 'function') {
        alert('您的浏览器不支持Websocket通信协议,请更换浏览器为Chrome或者Firefox再次使用!')
        return
      }
      this.userInfo = localStorage.getItem('user')
        ? JSON.parse(localStorage.getItem('user')).data
        : ''
      this.socket && this.socket.close()
      if (!this.socket) {
        // console.log("建立websocket连接");
        // this.socket = new WebSocket(`wss://admin.chnlovesky.com:2348`)
        // this.socket = new WebSocket(`wss://d0101.42.huizhouyiren.com:2349`)
        this.socket= new WebSocket(import.meta.env.VITE_SOCKET_URL)
        this.socket.onopen = () => {
          // this.dispatch("chat/sendPing");
          let userStore = useUser()
          this.sendSocketMessage({
            type: 'init',
            name: userStore.userInfo.nickname,
            to_mid: userStore.userInfo.id,
            avatar: userStore.userInfo.avatar
          })
        }
        this.socket.onmessage = (e) => {
          this.receiveMessage(e)
        }
        this.socket.onerror = () => {
          // console.log("连接失败重连中");
          this.socket.close()
          clearInterval(this.setIntervalWesocketPush)
          this.setIntervalWesocketPush = null
          if (this.socket.readyState !== 3) {
            this.socket = null
            this.createSocket()
          }
        }
        this.socket.onclose = () => {
          if (this.socket) {
            // console.log("websocket已断开....正在尝试重连");
            clearInterval(this.setIntervalWesocketPush)
            this.setIntervalWesocketPush = null
            if (this.socketreadyState !== 2) {
              this.socket = null
              this.createSocket()
            }
          }
        }
      } else {
        // console.log('websocket已连接')
      }
    },
    /**
     * @description: 发送消息
     * @param {*} payload
     * @return {*}
     */
    sendSocketMessage(payload) {
      let data = {
        ...payload
      }
      if (this.socket !== null && this.socket.readyState === 3) {
        this.socket.close()
        this.createSocket()
      } else if (this.socket.readyState === 1) {
        this.socket.send(JSON.stringify(data))
      } else if (this.socket.readyState === 0) {
        // this.dispatch("chat/resendMessage", message);
        this.messageQueue.push(data) // 添加到待发消息队列中
      }
    },
    /**
     * @description: 消息重发
     * @return {*}
     */
    resendMessage() {
      let messageQueue = [...this.messageQueue]
      this.messageQueue.forEach((item) => {
        if (this.socket?.readyState === 1) {
          this.socket.send(JSON.stringify(item))
          messageQueue.shift()
        } else if (this.socket.readyState === 0) {
          return
        }
      })
      this.messageQueue = messageQueue
    },
    /**
     * @description: 发送心跳包
     * @param {*} time
     * @return {*}
     */
    sendPing(time = 5000) {
      clearInterval(this.setIntervalWesocketPush)
      let ping = JSON.stringify({
        handlerType: 100
      })
      this.socket.send(ping)
      this.setIntervalWesocketPush = setInterval(() => {
        this.socket.send(ping)
      }, time)
    },
    /**
     * @description: 关闭socket连接
     * @return {*}
     */
    closeWebsocket() {
      this.socket.close()
    }
  }
})
